package com.system.controller.admin;

import com.alibaba.fastjson.JSON;
import com.common.Enums.UserEnum;
import com.common.annotation.LogInfo;
import com.common.exception.CourseException;
import com.common.util.CopyUtil;
import com.common.util.Excel.ExcelUtil;
import com.common.util.RedisUtil;
import com.common.util.ip.AddressUtils;
import com.common.util.ip.IpUtils;
import com.core.system.controller.UserController;
import com.core.system.domain.User;
import com.core.system.service.UserService;
import com.system.Excel.UserExcel;
import com.system.Excel.UserImporter;
import com.system.config.Constants;
import com.system.dto.LoginUserDto;
import com.system.dto.OnlineUserDto;
import com.system.dto.UserDto;
import com.system.service.UserExService;
import com.system.util.JWTUtils;
import eu.bitwalker.useragentutils.UserAgent;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;

@RestController
@RequestMapping("/admin/user")
@Api(value = "后台用户控制层",tags = {"后台用户控制层"})
@LogInfo
public class UserExController {
    private static final Logger LOG = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;
    @Autowired
    private UserExService userExService;
    @Resource(name = "carSocketExecutor")
    private ExecutorService executorService;
    @Resource
    public StringRedisTemplate stringRedisTemplate;
    @Resource
    private AuthenticationManager authenticationManager;


    @ApiOperation("修改后台用户密码接口")
    @PostMapping("/savepassword")
    @PreAuthorize("hasAnyAuthority(@servletUtils.getUrl)")
    public ResponseEntity updPassword(@RequestBody UserDto userDto){
        userDto.setPassword(DigestUtils.md5DigestAsHex(userDto.getPassword().getBytes()));
        return userExService.savePassword(userDto);
    }

    @ApiOperation("后台用户登录接口")
    @PostMapping("/login")
    public ResponseEntity login(@RequestBody UserDto userDto, HttpServletRequest request) {
        userDto.setPassword(DigestUtils.md5DigestAsHex(userDto.getPassword().getBytes()));
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDto.getUsername(), userDto.getPassword());
        String imageCode = stringRedisTemplate.opsForValue().get("code::"+userDto.getImageCodeToken());
        LOG.info("从redis中获取到的验证码：{}", imageCode);
        if (StringUtils.isEmpty(imageCode)) {
            throw new CourseException(UserEnum.IMGE_CODE_TIMEOUT);
        }
        if (!imageCode.equalsIgnoreCase(userDto.getImageCode())) {
            throw new CourseException(UserEnum.IMGE_CODE_ERROR);
        } else {
            stringRedisTemplate.delete(userDto.getImageCodeToken());
        }
//        LoginUserDto loginUserDto = userService.login(userDto);
        Authentication authenticate = authenticationManager.authenticate(token);
        UserDto loginUserDto= (UserDto) authenticate.getPrincipal();
        loginUserDto.setPassword(null);
        loginUserDto.setToken(JWTUtils.create(BeanMap.create(loginUserDto)));
        return ResponseEntity.ok(loginUserDto);

    }
    /**
     * 登录通知
     * @param request
     * @param loginUserDto
     */
    private  void loginNotice(HttpServletRequest request, LoginUserDto loginUserDto) {
        executorService.execute(()->{
            UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
            String ip = IpUtils.getIpAddr(request);
            // 获取客户端操作系统
            String os = userAgent.getOperatingSystem().getName();
            // 获取客户端浏览器
            String browser = userAgent.getBrowser().getName();
            String address = AddressUtils.getRealAddressByIP(ip);
            OnlineUserDto onlineUserDto = CopyUtil.copy(loginUserDto, OnlineUserDto.class);
            onlineUserDto.setOs(os);
            onlineUserDto.setHost(ip);
            onlineUserDto.setAddress(address);
            onlineUserDto.setBrowser(browser);
            onlineUserDto.setLogintime(new Date());
            RedisUtil.convertAndSend(Constants.LOGIN_TOPIC, JSON.toJSONString(onlineUserDto));//发布登录消息
        });
    }

    @ApiOperation("后台用户退出登录接口")
    @GetMapping("/logout/{token}")
    public ResponseEntity logout(@PathVariable("token")String token) {
        UserDto userDto = JWTUtils.verify(token);
        stringRedisTemplate.delete(String.format(Constants.TOKEN_List, userDto.getId()));
        LOG.info("从redis中删除token:{}", token);
        return ResponseEntity.ok().build();
    }

    @ApiOperation("用户导出")
    @PostMapping("/export")
    @PreAuthorize("hasAnyAuthority(@servletUtils.getUrl)")
    public void  export(HttpServletResponse response){
        ExcelUtil.export(response, "用户数据", "用户数据表",  userExService.ExportList(), UserExcel.class);
    }

    @PostMapping("/uploadExcel")
    @ApiOperation("用户文件信息上传接口")
     @PreAuthorize("hasAnyAuthority(@servletUtils.getUrl)")
    public ResponseEntity uploadExcel(@RequestParam("file") MultipartFile multipartFile) {
        UserImporter userImporter = new UserImporter(this.userExService, Boolean.valueOf(true));
        ExcelUtil.save(multipartFile,userImporter, User.class);
        return ResponseEntity.ok("上传成功");
    }


    @PostMapping("/exportTemplate")
    @ApiOperation("导出用户模板接口")
     @PreAuthorize("hasAnyAuthority(@servletUtils.getUrl)")
    public void exportTemplate(HttpServletResponse response) {
        List<UserExcel> list = new ArrayList<>();
        UserExcel excel = new UserExcel();
        excel.setName("张三");
        excel.setId("no123456");
        excel.setLoginName("张三");
        excel.setPassword("4db71c791e6a5f87027698565abc76c8");
        list.add(excel);
        ExcelUtil.export(response, "用户数据模板","用户数据模板表", list, UserExcel.class);
    }


}
